package com.oim.fx.view;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;

import javax.imageio.ImageIO;

import com.oim.common.event.ExecuteAction;
import com.oim.core.app.AppContext;
import com.oim.core.bean.Group;
import com.oim.core.bean.GroupMember;
import com.oim.core.bean.UserData;
import com.oim.core.business.controller.ChatController;
import com.oim.core.business.manage.ChatManage;
import com.oim.core.business.manage.ImageManage;
import com.oim.core.business.manage.LastManage;
import com.oim.core.business.manage.PathManage;
import com.oim.core.business.manage.PromptManage;
import com.oim.core.business.manage.SettingManage;
import com.oim.core.business.manage.VideoManage;
import com.oim.core.business.sender.ChatSender;
import com.oim.core.business.sender.GroupSender;
import com.oim.core.business.sender.VideoSender;
import com.oim.core.common.AppConstant;
import com.oim.core.common.action.CallBackAction;
import com.oim.core.common.app.view.AbstractView;
import com.oim.core.common.app.view.ChatListView;
import com.oim.core.common.box.GroupBox;
import com.oim.core.common.box.PersonalBox;
import com.oim.core.common.box.UserDataBox;
import com.oim.core.common.util.ColorUtil;
import com.oim.core.net.message.data.FileData;
import com.oim.core.net.message.data.UserChatHistoryData;
import com.oim.core.net.message.data.chat.Content;
import com.oim.core.net.server.Back;
import com.oim.fx.common.box.ImageBox;
import com.oim.fx.common.util.ContentUtil;
import com.oim.fx.ui.ChatListFrame;
import com.oim.fx.ui.chat.ChatItem;
import com.oim.fx.ui.chat.ChatPanel;
import com.oim.fx.ui.chat.SimpleHead;
//import com.oim.fx.ui.component.EmojiUtil;
import com.oim.fx.ui.component.IconButton;
import com.oim.fx.ui.component.IconStyleButton;
import com.oim.fx.ui.list.ListRootPanel;
import com.oim.swing.ui.chat.FacePanel;
import com.oim.swing.ui.chat.ScreenShotAction;
import com.oim.swing.ui.chat.ScreenShotWindow;
import com.only.common.result.Info;
import com.only.common.util.OnlyDateUtil;
import com.only.common.util.OnlyFileUtil;
import com.only.general.annotation.parameter.Define;
import com.only.net.data.action.DataBackAction;
import com.only.net.data.action.DataBackActionAdapter;

import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;

/**
 * 描述：
 *
 * @author XiaHui
 * @date 2015年3月14日 上午11:14:38
 * @version 0.0.1
 */
public class ChatListViewImpl extends AbstractView implements ChatListView {

	ChatListFrame chatListFrame = new ChatListFrame();

	private Map<String, ChatPanel> chatPanelMap = new ConcurrentHashMap<String, ChatPanel>();
	private Map<String, ChatItem> chatItemMap = new ConcurrentHashMap<String, ChatItem>();
	private ConcurrentSkipListMap<String, ChatItem> itemMap = new ConcurrentSkipListMap<String, ChatItem>();

	private Map<String, ListRootPanel> groupUserListMap = new ConcurrentHashMap<String, ListRootPanel>();

	private FileChooser imageFileChooser;
	private FileChooser fileChooser;

	FacePanel facePanel = FacePanel.getFacePanel();
	ScreenShotWindow ssw = ScreenShotWindow.getScreenShotWindow();

	SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSSS");

	ChatItem tempChatItem;
	private long shakeTime = 0;// 记录收到或者发送抖动信息的时间，为了不过于频繁抖动。

	public ChatListViewImpl(AppContext appContext) {
		super(appContext);

		imageFileChooser = new FileChooser();
		imageFileChooser.getExtensionFilters().add(new ExtensionFilter("图片文件", "*.png", "*.jpg", "*.bmp", "*.gif"));

		fileChooser = new FileChooser();
		// fileChooser.getExtensionFilters().add(new ExtensionFilter("文件"));
		initEvent();
	}

	private void initEvent() {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {

			}
		});
	}

	public boolean isShowing() {
		return chatListFrame.isShowing();
	}

	@Override
	public void setVisible(boolean visible) {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				if (visible) {
					chatListFrame.show();
					chatListFrame.toFront();
				} else {
					chatListFrame.hide();
				}
			}
		});
	}

	public boolean isGroupChatShowing(String groupId) {
		String key = this.getGroupKey(groupId);
		return chatListFrame.isShowing() && (null != tempChatItem && key.equals(tempChatItem.getAttribute("key")));
	}

	public boolean isUserChatShowing(String userId) {
		String key = this.getUserKey(userId);
		return chatListFrame.isShowing() && (null != tempChatItem && key.equals(tempChatItem.getAttribute("key")));
	}

	public void show(UserData userData) {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				ChatItem chatItem = getUserChatItem(userData);
				ChatPanel chatPanel = getUserChatPanel(userData);
				select(chatItem, chatPanel);
				ChatManage chatManage = appContext.getManage(ChatManage.class);
				chatManage.showUserCaht(userData);
			}
		});
	}

	public void show(Group group) {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				ChatItem chatItem = getGroupChatItem(group);
				ChatPanel chatPanel = getGroupChatPanel(group);
				select(chatItem, chatPanel);
				ChatManage chatManage = appContext.getManage(ChatManage.class);
				chatManage.showGroupCaht(group);
			}
		});
	}

	private ChatItem getUserChatItem(UserData userData) {
		String key = this.getUserKey(userData.getId());
		ChatItem item = chatItemMap.get(key);
		if (null == item) {
			item = new ChatItem();
			item.addAttribute("key", key);
			chatItemMap.put(key, item);
			item.addCloseAction(new ChatItemCloseEvent(key));
			item.setOnMouseClicked(new ChatItemClickedEvent(key));
		}

		if (null != userData.getRemark() && !"".equals(userData.getRemark())) {
			item.setText(userData.getRemark());
		} else {
			item.setText(userData.getNickname());
		}
		Image image = ImageBox.getImagePath("Resources/Images/Head/User/" + userData.getHead() + ".png", 34, 34, 8, 8);
		item.setImage(image);
		return item;
	}

	private ChatPanel getUserChatPanel(UserData userData) {
		String key = this.getUserKey(userData.getId());
		ChatPanel item = chatPanelMap.get(key);
		if (null == item) {
			item = new ChatPanel();
			item.addAttribute("key", key);
			item.addAttribute("userId", userData.getId());
			item.setSendAction(new ChatItemUserSendEvent(key));
			item.setCloseAction(new ChatItemCloseEvent(key));

			ExecuteAction faceAction = new ExecuteAction() {

				ChatPanel item;

				@Override
				public <T, E> E execute(T value) {
					if (null != value) {
						Platform.runLater(new Runnable() {
							public void run() {
								insertFace(item, value.toString());
							}
						});
					}
					return null;
				}

				ExecuteAction set(ChatPanel item) {
					this.item = item;
					return this;
				}
			}.set(item);

			// 表情按钮
			Image normalImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_face.png");
			Image hoverImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_face_hover.png");
			Image pressedImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_face_hover.png");
			IconButton iconButton = new IconButton(normalImage, hoverImage, pressedImage);
			iconButton.setOnMouseClicked(new EventHandler<MouseEvent>() {

				@Override
				public void handle(MouseEvent event) {

					facePanel.setSelectAction(faceAction);
					facePanel.show((int) event.getScreenX() - 240, (int) event.getScreenY());
				}
			});
			item.addMiddleTool(iconButton);
			// 发送图片按钮
			normalImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_sendpic.png");
			hoverImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_sendpic_hover.png");
			pressedImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_sendpic_hover.png");

			iconButton = new IconButton(normalImage, hoverImage, pressedImage);
			EventHandler<MouseEvent> e = new EventHandler<MouseEvent>() {
				ChatPanel item;

				@Override
				public void handle(MouseEvent event) {
					String fullPath = getPicture();
					item.insertImage("", "", "", fullPath);
				}

				EventHandler<MouseEvent> set(ChatPanel item) {
					this.item = item;
					return this;
				}
			}.set(item);
			iconButton.setOnMouseClicked(e);
			item.addMiddleTool(iconButton);

			ScreenShotAction screenShotAction = new ScreenShotAction() {

				ChatPanel item;

				@Override
				public void saveImage(BufferedImage image) {

					Platform.runLater(new Runnable() {
						public void run() {
							if (null != image) {
								saveBufferedImage(item, image);
							}
						}
					});
				}

				ScreenShotAction set(ChatPanel item) {
					this.item = item;
					return this;
				}
			}.set(item);
			// 截屏按钮
			normalImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_cut.png");
			hoverImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_cut.png");
			pressedImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_cut.png");

			iconButton = new IconButton(normalImage, hoverImage, pressedImage);
			iconButton.setOnMouseClicked(new EventHandler<MouseEvent>() {

				@Override
				public void handle(MouseEvent event) {
					ssw.setAction(screenShotAction);
					ssw.setVisible(true);
				}
			});
			item.addMiddleTool(iconButton);

			normalImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_twitter.png");

			iconButton = new IconButton(normalImage);
			item.addMiddleTool(iconButton);

			iconButton.setOnMouseClicked(new EventHandler<MouseEvent>() {

				@Override
				public void handle(MouseEvent event) {
					sendShake(userData.getId());
				}
			});

			normalImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/GVideoTurnOnVideo.png");

			iconButton = new IconButton(normalImage);
			item.addMiddleTool(iconButton);

			iconButton.setOnMouseClicked(new EventHandler<MouseEvent>() {

				@Override
				public void handle(MouseEvent event) {
					sendVideo(userData);
				}
			});

			normalImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_register.png");
			hoverImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_register_hover.png");
			pressedImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_register.png");

			iconButton = new IconButton("消息记录", normalImage, hoverImage, pressedImage);
			iconButton.setOnMouseClicked(new EventHandler<MouseEvent>() {

				@Override
				public void handle(MouseEvent event) {
					showChatHistoryView(userData.getId());
					PromptManage pm = appContext.getManage(PromptManage.class);
					pm.remove("offline," + userData.getId());// 系统托盘停止跳动
				}
			});

			item.addMiddleRightTool(iconButton);

			chatPanelMap.put(key, item);
			StackPane rightPane = new StackPane();
			// rightPane.setPrefHeight(350);
			// rightPane.setMaxHeight(350);
			ImageView imageView = new ImageView();
			rightPane.getChildren().add(imageView);

			if (!"女".equals(userData.getGender())) {
				Image image = ImageBox.getImagePath("Resources/Images/Default/Show/default_av_girl_v3.png", 140, 380);
				imageView.setImage(image);
			} else {
				Image image = ImageBox.getImagePath("Resources/Images/Default/Show/default_av_boy_v3.png", 140, 380);
				imageView.setImage(image);
			}
			item.setRightPane(rightPane);

			Image i = ImageBox.getImageClassPath("/resources/chat/images/user/file/aio_toobar_send_hover.png");

			IconStyleButton isb = new IconStyleButton();
			isb.setImage(i);
			item.addTopTool(isb);

			isb.setOnAction(a -> {
				File file = fileChooser.showOpenDialog(chatListFrame);
				if (null != file) {
					SettingManage sm = appContext.getManage(SettingManage.class);
					if (file.length() > sm.getChatSetting().getFileLimitSize()) {
						chatListFrame.showPrompt(sm.getChatSetting().getFileLimitInfo());
						return;
					}
					ChatController cc = appContext.getController(ChatController.class);
					cc.sendFile(userData.getId(), file);
				}
			});

			item.setFileEventAction(file -> {
				if (null != file) {
					SettingManage sm = appContext.getManage(SettingManage.class);
					if (file.length() > sm.getChatSetting().getFileLimitSize()) {
						chatListFrame.showPrompt(sm.getChatSetting().getFileLimitInfo());
						return;
					}
					ChatController cc = appContext.getController(ChatController.class);
					cc.sendFile(userData.getId(), file);
				}
			});
		}

		if (null != userData.getRemark() && !"".equals(userData.getRemark())) {
			item.setName(userData.getRemark());
		} else {
			item.setName(userData.getNickname());
		}
		item.setText(userData.getSignature());
		return item;
	}

	///////////////////////////////////////////////////////// group
	private ChatItem getGroupChatItem(Group group) {
		String key = this.getGroupKey(group.getId());
		ChatItem item = chatItemMap.get(key);
		if (null == item) {
			item = new ChatItem();
			item.addAttribute("key", key);
			chatItemMap.put(key, item);
			item.addCloseAction(new ChatItemCloseEvent(key));
			item.setOnMouseClicked(new ChatItemClickedEvent(key));
		}

		item.setText(group.getName());
		Image image = ImageBox.getImagePath("Resources/Images/Head/Group/" + group.getHead() + ".png", 34, 34, 8, 8);
		item.setImage(image);
		return item;
	}

	private ChatPanel getGroupChatPanel(Group group) {
		String key = this.getGroupKey(group.getId());
		ChatPanel item = chatPanelMap.get(key);
		if (null == item) {
			item = new ChatPanel();
			item.addAttribute("key", key);
			item.addAttribute("groupId", group.getId());
			item.setSendAction(new ChatItemGroupSendEvent(key));
			item.setCloseAction(new ChatItemCloseEvent(key));
			chatPanelMap.put(key, item);
			setGroupUserListPane(item, group.getId());

			ExecuteAction faceAction = new ExecuteAction() {

				ChatPanel item;

				@Override
				public <T, E> E execute(T value) {
					if (null != value) {
						Platform.runLater(new Runnable() {
							public void run() {
								insertFace(item, value.toString());
							}
						});
					}
					return null;
				}

				ExecuteAction set(ChatPanel item) {
					this.item = item;
					return this;
				}
			}.set(item);

			// 表情按钮
			Image normalImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_face.png");
			Image hoverImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_face_hover.png");
			Image pressedImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_face_hover.png");
			IconButton iconButton = new IconButton(normalImage, hoverImage, pressedImage);
			iconButton.setOnMouseClicked(new EventHandler<MouseEvent>() {

				@Override
				public void handle(MouseEvent event) {

					facePanel.setSelectAction(faceAction);
					facePanel.show((int) event.getScreenX() - 240, (int) event.getScreenY());
				}
			});
			item.addMiddleTool(iconButton);
			// 发送图片按钮
			normalImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_sendpic.png");
			hoverImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_sendpic_hover.png");
			pressedImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_sendpic_hover.png");

			iconButton = new IconButton(normalImage, hoverImage, pressedImage);
			EventHandler<MouseEvent> e = new EventHandler<MouseEvent>() {
				ChatPanel item;

				@Override
				public void handle(MouseEvent event) {
					String fullPath = getPicture();
					item.insertImage("", "", "", fullPath);
				}

				EventHandler<MouseEvent> set(ChatPanel item) {
					this.item = item;
					return this;
				}
			}.set(item);
			iconButton.setOnMouseClicked(e);
			item.addMiddleTool(iconButton);

			ScreenShotAction screenShotAction = new ScreenShotAction() {

				ChatPanel item;

				@Override
				public void saveImage(BufferedImage image) {

					Platform.runLater(new Runnable() {
						public void run() {
							if (null != image) {
								saveBufferedImage(item, image);
							}
						}
					});
				}

				ScreenShotAction set(ChatPanel item) {
					this.item = item;
					return this;
				}
			}.set(item);
			// 截屏按钮
			normalImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_cut.png");
			hoverImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_cut.png");
			pressedImage = ImageBox.getImageClassPath("/resources/chat/images/middletoolbar/aio_quickbar_cut.png");

			iconButton = new IconButton(normalImage, hoverImage, pressedImage);
			iconButton.setOnMouseClicked(new EventHandler<MouseEvent>() {

				@Override
				public void handle(MouseEvent event) {
					ssw.setAction(screenShotAction);
					ssw.setVisible(true);
				}
			});
			item.addMiddleTool(iconButton);

		}
		item.setName(group.getName());
		item.setText(group.getPublicNotice());
		return item;
	}

	//////////////////////////////////////////////////////////
	private void select(ChatItem item, ChatPanel chatPanel) {
		if (item != this.tempChatItem) {
			if (null != this.tempChatItem) {
				this.tempChatItem.setSelected(false);
			}
			item.setSelected(true);
		}
		this.tempChatItem = item;
		chatListFrame.addItem(item);
		chatListFrame.setChatPanel(chatPanel);
		if (!itemMap.containsValue(item)) {
			String key = item.getAttribute("key");
			itemMap.put(key, item);
		}
	}

	@Override
	public boolean hasGroupChat(String groupId) {
		String key = getGroupKey(groupId);
		return chatItemMap.containsKey(key);
	}

	@Override
	public boolean hasUserChat(String userId) {
		String key = getUserKey(userId);
		return chatItemMap.containsKey(key);
	}

	private void sendVideo(UserData userData) {
		UserData sendUser = PersonalBox.get(UserData.class);
		VideoManage vm = this.appContext.getManage(VideoManage.class);
		vm.showSendVideoFrame(userData);
		VideoSender vh = this.appContext.getSender(VideoSender.class);
		vh.requestVideo(sendUser.getId(), userData.getId());
	}

	@Override
	public void userChat(boolean isOwn, UserData userData, Content content) {
		if (null != userData) {
			String name = userData.getNickname();
			String time = OnlyDateUtil.dateToString(new Date(content.getTimestamp()), "yyyy-MM-dd HH:mm:ss");
			String color = ColorUtil.getColorInHexFromRGB(Color.blue.getRed(), Color.blue.getGreen(), Color.blue.getBlue());// ColorUtil.getColorInHexFromRGB(32,
			ChatPanel chatPanel = getUserChatPanel(userData);
			insertShowChat(chatPanel, name, color, time, content); // 143,
		}
	}

	public void groupChat(Group group, UserData userData, Content content) {
		if (null != userData) {
			UserData user = PersonalBox.get(UserData.class);
			boolean isOwn = user.getId().equals(userData.getId());
			String name = userData.getNickname();
			String time = OnlyDateUtil.getCurrentDateTime();
			String color = (isOwn) ? ColorUtil.getColorInHexFromRGB(32, 143, 62) : ColorUtil.getColorInHexFromRGB(Color.blue.getRed(), Color.blue.getGreen(), Color.blue.getBlue());
			ChatPanel chatPanel = getGroupChatPanel(group);
			insertShowChat(chatPanel, name, color, time, content);
		}
	}

	private void insertShowChat(ChatPanel cp, String name, String color, String time, Content content) {
		if (null != cp) {
			String nameTag = ContentUtil.getInsertNameTag(name, color, time);
			String contentTag = ContentUtil.getInsertContentTag(content);

			Platform.runLater(new Runnable() {
				@Override
				public void run() {
					cp.insertShowLastHtml(nameTag);
					cp.insertShowLastHtml(contentTag);
				}
			});
			if(ContentUtil.hasImage(content)){
				UserData sendUser = PersonalBox.get(UserData.class);
				CallBackAction<List<FileData>> fileBackAction = new CallBackAction<List<FileData>>() {

					@Override
					public void execute(List<FileData> list) {

						for (FileData fd : list) {
							String name = fd.getName();
							String path = "file:/" + AppConstant.userHome + "/" + AppConstant.app_home_path + "/" + sendUser.getNumber() + "/image/" + name;
							Platform.runLater(new Runnable() {
								@Override
								public void run() {
									cp.replaceImage(fd.getId(), path);
								}
							});
						}
					}
				};
				ImageManage im = this.appContext.getManage(ImageManage.class);
				im.downloadImage(content, fileBackAction);
			}
		}
	}

	private void sendUserMessage(String key) {
		UserData sendUser = PersonalBox.get(UserData.class);
		ChatPanel chatPanel = chatPanelMap.get(key);
		if (null != chatPanel) {
			String html = chatPanel.getHtml();

			boolean underline = chatPanel.isUnderline();
			boolean bold = chatPanel.isBold();
			String color = chatPanel.getWebColor();
			boolean italic = chatPanel.isItalic();
			String fontName = chatPanel.getFontName();
			int fontSize = chatPanel.getFontSize();
			Content content = ContentUtil.getContent(html, fontName, fontSize, color, underline, bold, italic);
			String receiveUserId = chatPanel.getAttribute("userId");
			if (null != content) {
				chatPanel.initializeWriteHtml();

				String name = sendUser.getNickname();
				String time = OnlyDateUtil.getCurrentDateTime();
				String nameColor = ColorUtil.getColorInHexFromRGB(32, 143, 62);

				DataBackActionAdapter action = new DataBackActionAdapter() {
					@Back
					public void back(Info info, @Define("userData") UserData user) {
						if (info.isSuccess()) {
							UserData userData = UserDataBox.get(receiveUserId);
							if (null != userData) {
								LastManage lastManage = appContext.getManage(LastManage.class);
								String text=ContentUtil.getText(content);
								lastManage.addOrUpdateLastUserData(userData,text);
							}
						}
					}
				};
				if (ContentUtil.hasImage(content)) {
					CallBackAction<List<FileData>> fileBackAction = new CallBackAction<List<FileData>>() {

						@Override
						public void execute(List<FileData> list) {

							for (FileData fd : list) {
								String name = fd.getName();
								String path = "file:/" + AppConstant.userHome + "/" + AppConstant.app_home_path + "/" + sendUser.getNumber() + "/image/" + name;
								Platform.runLater(new Runnable() {
									@Override
									public void run() {
										chatPanel.replaceImage(fd.getId(), path);
									}
								});
							}
						}
					};

					ImageManage im = this.appContext.getManage(ImageManage.class);
					CallBackAction<Boolean> callBackAction = new CallBackAction<Boolean>() {

						@Override
						public void execute(Boolean t) {
							ChatSender ch = appContext.getSender(ChatSender.class);
							ch.sendUserChatMessage(receiveUserId, sendUser.getId(), content, action);
							Platform.runLater(new Runnable() {
								@Override
								public void run() {
									insertShowChat(chatPanel, name, nameColor, time, content);
								}
							});
							im.handleLocalImage(content, fileBackAction);
						}
					};
					im.handleImage(content, callBackAction);
				}else{
					ChatSender ch = appContext.getSender(ChatSender.class);
					ch.sendUserChatMessage(receiveUserId, sendUser.getId(), content, action);
					Platform.runLater(new Runnable() {
						@Override
						public void run() {
							insertShowChat(chatPanel, name, nameColor, time, content);
						}
					});
				}
			}
		}
	}

	private void sendGroupMessage(String key) {
		UserData user = PersonalBox.get(UserData.class);
		ChatPanel chatPanel = chatPanelMap.get(key);
		if (null != chatPanel) {
			String html = chatPanel.getHtml();

			boolean underline = chatPanel.isUnderline();
			boolean bold = chatPanel.isBold();
			String color = chatPanel.getWebColor();
			boolean italic = chatPanel.isItalic();
			String fontName = chatPanel.getFontName();
			int fontSize = chatPanel.getFontSize();
			Content content = ContentUtil.getContent(html, fontName, fontSize, color, underline, bold, italic);
			String groupId = chatPanel.getAttribute("groupId");
			if (null != content) {
				chatPanel.initializeWriteHtml();
				if (ContentUtil.hasImage(content)) {//判断信息中是否有图片，没有图片直接发送，节省响应事件
					ImageManage im = this.appContext.getManage(ImageManage.class);
					CallBackAction<Boolean> callBackAction = new CallBackAction<Boolean>() {
						@Override
						public void execute(Boolean t) {
							ChatSender ch = appContext.getSender(ChatSender.class);
							ch.sendGroupChatMessage(groupId, user.getId(), content);
						}
					};
					im.handleImage(content, callBackAction);
				} else {
					ChatSender ch = appContext.getSender(ChatSender.class);
					ch.sendGroupChatMessage(groupId, user.getId(), content);
				}
			}
		}
	}

	private void selectChatItem(String key) {
		ChatItem ci = chatItemMap.get(key);
		ChatPanel cp = chatPanelMap.get(key);
		if (null != ci && null != cp) {
			select(ci, cp);
		}
	}

	private void removeChatItem(String key) {
		ChatItem item = chatItemMap.get(key);
		if (null != item) {
			chatListFrame.removeItem(item);
			itemMap.remove(key);

			if (itemMap.isEmpty()) {
				setVisible(false);
			} else {
				if (item.isSelected()) {
					Iterator<String> iterator = itemMap.keySet().iterator();
					if (iterator.hasNext()) {
						String nextKey = iterator.next();
						selectChatItem(nextKey);
					}
				}
			}
		}
	}

	private String getUserKey(String userId) {
		StringBuilder sb = new StringBuilder();
		sb.append("user_");
		sb.append(userId);
		return sb.toString();
	}

	private String getGroupKey(String groupId) {
		StringBuilder sb = new StringBuilder();
		sb.append("group_");
		sb.append(groupId);
		return sb.toString();
	}

	private void setGroupUserListPane(ChatPanel item, String groupId) {
		ListRootPanel groupUserList = groupUserListMap.get(groupId);
		if (null == groupUserList) {
			updateGroupUserList(groupId);
		} else {
			if (null != item) {
				item.setRightPane(groupUserList);
			}
		}
	}

	public void setGroupUserList(final String groupId) {
		List<GroupMember> gml = GroupBox.getGroupMemberList(groupId);
		if (null == gml) {
			DataBackAction dataBackAction = new DataBackActionAdapter() {
				@Back
				public void back(@Define("userDataList") List<UserData> userDataList, @Define("groupMemberList") List<GroupMember> groupMemberList) {
					setGroupUserList(groupId, userDataList, groupMemberList);
				}
			};
			GroupSender gh = this.appContext.getSender(GroupSender.class);
			gh.getGroupMemberListWithUserDataList(groupId, dataBackAction);
		}
	}

	public void updateGroupUserList(final String groupId) {

		DataBackAction dataBackAction = new DataBackActionAdapter() {

			@Back
			public void back(@Define("userDataList") List<UserData> userDataList, @Define("groupMemberList") List<GroupMember> groupMemberList) {
				setGroupUserList(groupId, userDataList, groupMemberList);
			}
		};
		GroupSender gh = this.appContext.getSender(GroupSender.class);
		gh.getGroupMemberListWithUserDataList(groupId, dataBackAction);
	}

	private void setGroupUserList(String groupId, List<UserData> userDataList, List<GroupMember> groupMemberList) {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				GroupBox.put(groupId, groupMemberList);
				ListRootPanel groupUserList = groupUserListMap.get(groupId);
				if (groupUserList == null) {
					groupUserList = new ListRootPanel();
				}
				groupUserList.clearNode();
				for (UserData userData : userDataList) {
					SimpleHead item = new SimpleHead();

					item.setOnMouseClicked((MouseEvent me) -> {
						if (me.getClickCount() == 2) {
							ChatManage chatManage = appContext.getManage(ChatManage.class);
							chatManage.showCahtFrame(userData);
						}
						me.consume();
					});
					item.setText(userData.getNickname());
					Image image = ImageBox.getImagePath("Resources/Images/Head/User/" + userData.getHead() + ".png", 20, 20);
					item.setImage(image);
					item.addAttribute(UserData.class, userData);
					groupUserList.addNode(item);
				}

				String key = getGroupKey(groupId);
				ChatPanel chatPanel = chatPanelMap.get(key);
				if (null != chatPanel) {
					chatPanel.setRightPane(groupUserList);
				}
			}
		});
	}

	private class ChatItemGroupSendEvent implements EventHandler<ActionEvent> {

		String key;

		public ChatItemGroupSendEvent(String key) {
			this.key = key;
		}

		@Override
		public void handle(ActionEvent event) {
			sendGroupMessage(key);
		}
	}

	private class ChatItemUserSendEvent implements EventHandler<ActionEvent> {

		String key;

		public ChatItemUserSendEvent(String key) {
			this.key = key;
		}

		@Override
		public void handle(ActionEvent event) {
			sendUserMessage(key);
		}
	}

	private class ChatItemCloseEvent implements EventHandler<ActionEvent> {

		String key;

		public ChatItemCloseEvent(String key) {
			this.key = key;
		}

		@Override
		public void handle(ActionEvent event) {
			removeChatItem(key);
		}
	}

	private class ChatItemClickedEvent implements EventHandler<MouseEvent> {

		String key;

		public ChatItemClickedEvent(String key) {
			this.key = key;
		}

		@Override
		public void handle(MouseEvent event) {
			selectChatItem(key);
		}
	}

	/**
	 * 发送抖动操作
	 * 
	 * @Author: XiaHui
	 * @Date: 2016年2月16日
	 * @ModifyUser: XiaHui
	 * @ModifyDate: 2016年2月16日
	 * @param receiveId
	 */
	private void sendShake(String receiveId) {
		UserData sendUser = PersonalBox.get(UserData.class);
		ChatSender ch = this.appContext.getSender(ChatSender.class);
		ch.sendShake(receiveId, sendUser.getId());// 发送给接受方
		shake();// 自己执行抖动
	}

	@Override
	public void doShake(UserData userData) {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				ChatItem chatItem = getUserChatItem(userData);
				ChatPanel chatPanel = getUserChatPanel(userData);
				select(chatItem, chatPanel);
				ChatManage chatManage = appContext.getManage(ChatManage.class);
				chatManage.showUserCaht(userData);
				shake();
			}
		});
	}

	private void shake() {
		if (System.currentTimeMillis() - shakeTime < 3000) {
			return;
		}
		Platform.runLater(new Runnable() {
			@Override
			public void run() {

				Task<Integer> task = new Task<Integer>() {
					@Override
					protected Integer call() throws Exception {
						int iterations = 0;
						for (int i = 0; i < 3; i++) {
							chatListFrame.setX(chatListFrame.getX() + 4);
							chatListFrame.setY(chatListFrame.getY() - 4);
							try {
								Thread.sleep(40);
								chatListFrame.setX(chatListFrame.getX() - 8);
								chatListFrame.setY(chatListFrame.getY());
								Thread.sleep(40);
								chatListFrame.setX(chatListFrame.getX());
								chatListFrame.setY(chatListFrame.getY() + 4);
								Thread.sleep(40);
								chatListFrame.setX(chatListFrame.getX() + 4);
								chatListFrame.setY(chatListFrame.getY());
								Thread.sleep(40);
							} catch (InterruptedException ex) {
								ex.printStackTrace();
							}
						}
						return iterations;
					}
				};

				Thread th = new Thread(task);
				th.setDaemon(true);
				th.start();
			}
		});
		shakeTime = System.currentTimeMillis();
	}

	public void saveBufferedImage(ChatPanel cp, BufferedImage image) {
		String fileName = dateFormat.format(new Date()).toString() + ".jpg";
		PathManage pm = appContext.getManage(PathManage.class);
		String savePath = pm.getScreenshotSavePath();
		String path = savePath + fileName;
		try {
			OnlyFileUtil.checkOrCreateFolder(path);
			ImageIO.write(image, "jpg", new File(path));
			cp.insertImage("", "", path, path);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private String getPicture() {
		String fullPath = null;
		File file = imageFileChooser.showOpenDialog(chatListFrame);
		if (file != null) {
			if (file.exists()) {
				SettingManage sm = appContext.getManage(SettingManage.class);
				if (file.length() > sm.getChatSetting().getImageLimitSize()) {
					chatListFrame.showPrompt(sm.getChatSetting().getImageLimitInfo());
					return null;
				}
				fullPath = file.getAbsolutePath();
			}
		}
		return fullPath;
	}

	private void insertFace(ChatPanel cp, String value) {
		String path = "Resources/Images/Face/" + value + ".gif ";
		File file = new File(path);
		if (file.exists()) {
			String fullPath = file.getAbsolutePath();
			String v = "classical" + "," + value;
			cp.insertImage("", "face", v, fullPath);
		}
	}

	
	///////////////////////////////////

	private Map<String, UserChatHistoryView> chvMap = new ConcurrentHashMap<String, UserChatHistoryView>();

	/**
	 * 显示历史记录
	 * 
	 * @param userId
	 */
	public void showChatHistoryView(String userId) {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				UserChatHistoryView chf = getChatHistoryView(userId);
				chf.setVisible(true);
			}
		});
	}

	public UserChatHistoryView getChatHistoryView(String userId) {

		UserChatHistoryView chv = chvMap.get(userId);
		if (null == chv) {
			chv = appContext.getNewView(UserChatHistoryView.class);
			chv.setUserId(userId);
			chvMap.put(userId, chv);
		}
		return chv;
	}

	@Override
	public void userChatHistory(UserData userData, List<UserChatHistoryData> contents) {

		StringBuilder div = new StringBuilder();
		div.append("<div>");
		if (null != contents) {
			for (UserChatHistoryData chd : contents) {
				UserData sendUserData = chd.getSendUserData();
				Content content = chd.getContent();
				String name = sendUserData.getNickname();
				String time = OnlyDateUtil.dateToDateTime(new Date(content.getTimestamp()));
				String greenColor = ColorUtil.getColorInHexFromRGB(32, 143, 62);
				String blueColor = ColorUtil.getColorInHexFromRGB(Color.blue.getRed(), Color.blue.getGreen(), Color.blue.getBlue());
				UserData user = PersonalBox.get(UserData.class);
				boolean isOwn = user.getId().equals(sendUserData.getId());

				String nameTag = ContentUtil.getInsertNameTag(name, isOwn ? greenColor : blueColor, time);
				div.append(nameTag);
				String contentTag = ContentUtil.getInsertContentTag(content);
				div.append(contentTag);
			}

		}
		div.append("</div>");
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				ChatPanel chatPanel = getUserChatPanel(userData);
				chatPanel.insertShowLastHtml(div.toString());
			}
		});

		UserData user = PersonalBox.get(UserData.class);
		CallBackAction<List<FileData>> fileBackAction = new CallBackAction<List<FileData>>() {

			@Override
			public void execute(List<FileData> list) {

				for (FileData fd : list) {
					String name = fd.getName();
					String path = "file:/" + AppConstant.userHome + "/" + AppConstant.app_home_path + "/" + user.getNumber() + "/image/" + name;
					Platform.runLater(new Runnable() {
						@Override
						public void run() {
							ChatPanel chatPanel = getUserChatPanel(userData);
							chatPanel.replaceImage(fd.getId(), path);
						}
					});
				}
			}
		};
		if (null != contents) {
			for (UserChatHistoryData chd : contents) {
				Content content = chd.getContent();
				ImageManage im = this.appContext.getManage(ImageManage.class);
				im.downloadImage(content, fileBackAction);
			}
		}
	}
}
